<template>
  <div class="be-form">
    <a-form ref="formRef" v-bind="getBindValue" :labelCol="labelCol" :wrapperCol="wrapperCol" :model="formModel" :rules="visibleRules">
      <a-row v-bind="rowProps || { gutter: 16 }">
        <template v-for="(item, index) in visibleFields" :key="item.name">
          <a-col v-bind="item.colProps" v-show="showFormItem(item, index)">
            <a-form-item :label="item.label" :name="item.prop" v-bind="item.formItemProps">
              <!-- 插槽优先，可完全自定义表单项 -->
              <template v-if="$slots[item.prop]">
                <slot :name="item.prop" :model="formModel" :field="item"></slot>
              </template>
              <!-- 否则自动渲染配置的组件 -->
              <template v-else>
                <component
                  v-if="item.component"
                  :is="typeof item.component === 'string' ? componentMap.get(item.component) : item.component"
                  v-model:[getValuePropName(item)]="formModel[item.prop]"
                  v-bind="item.componentProps"
                />
              </template>
            </a-form-item>
          </a-col>
        </template>

        <!-- 操作按钮区-->
        <a-col v-bind="actionColProps" v-if="showAction">
          <div class="action-wrap">
            <BeButton v-if="showSearchButton" class="action-btn" type="primary" @click="handleSearch">
              <!-- <BeIcon icon="local:search" /> -->
              <span class="text">查询</span>
            </BeButton>
            <BeButton v-if="showResetButton" class="action-btn" @click="reset" style="background: none; border: none; box-shadow: none; color: #1890ff">
              <span class="text">重置</span>
              <BeIcon icon="local:refresh" />
            </BeButton>
            <template v-if="showExpandButton && maxShowFields < fields.length">
              <BeButton class="action-btn expand-btn" :class="{ expand: expanded }" type="link" @click="handleToggleExpand()">
                <span class="text">{{ expanded ? '收起' : '展开' }}</span>
                <BeIcon icon="local:arrow" />
              </BeButton>
            </template>
          </div>
          <slot name="action" :reset="reset" :model="formModel"></slot>
        </a-col>
        <slot name="footer" :reset="reset" :model="formModel"></slot>
      </a-row>
    </a-form>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { componentMap } from './componentMap'
import { FieldItem, Props } from './types'

defineOptions({ name: 'BeForm', inheritAttrs: false })

// 定义 props 和默认值
const props = withDefaults(defineProps<Props>(), {
  maxShowFields: -1,
  modelValue: () => ({}),
  showAction: true,
  showExpand: true,
  actionColProps: () => ({ xs: 24, sm: 8, md: 6, lg: 6, xl: 6, xxl: 6 }),
  defultValue: () => ({})
})

// emit
const emit = defineEmits(['update:modelValue', 'search', 'reset', 'toggleExpand'])

// state
const attrs = useAttrs()
const formRef = ref()
const formModel = ref<Record<string, any>>({})
const expanded = ref(false) // 计算是否需要展示展开收起按钮
const getBindValue = computed(() => attrs) // 需要绑定的属性
// 显示的表单
const visibleFields = computed(() => {
  const fields = props.fields
  return fields
    .filter((field) => {
      const { show } = field
      if (typeof show === 'boolean') return show
      if (typeof show === 'function') return show(formModel.value, field)
      return true // 默认显示
    })
    .map((field: FieldItem) => {
      field.formItemProps = field.formItemProps || {}
      const colProps = field.colProps || {}
      const ifShow = typeof field.ifShow === 'function' ? field.ifShow(formModel.value, field) : (field.ifShow ?? true)
      field.formItemProps.rules = ifShow ? field.formItemProps?.rules : []
      // 仅当 component 是 Proxy（即是响应式）才需要 markRaw
      if (field.component && isProxy(field.component) && (typeof field.component === 'function' || typeof field.component === 'object')) {
        field.component = markRaw(field.component)
      }
      return { ...field, colProps: { span: 12, ...props.colProps, ...colProps } }
    })
})
const visibleRules = computed(() => {
  const res: Record<string, any[]> = {}
  const baseRules: any = attrs.rules || {}
  props.fields.forEach((field) => {
    const ifShow = typeof field.ifShow === 'function' ? field.ifShow(formModel.value, field) : (field.ifShow ?? true)
    if (ifShow && field.prop && baseRules[field.prop]) {
      res[field.prop] = baseRules[field.prop]
    }
  })
  return res
})
const labelCol = computed(() => ({ style: { width: props.labelWidth || '70px' }, ...props.labelCol }))
const wrapperCol = computed(() => ({ ...props.wrapperCol }))

// 切换展开/收起状态
const handleToggleExpand = () => {
  expanded.value = !expanded.value
  emit('toggleExpand', expanded.value)
}

// 重置表单所有字段，清空数据并触发更新和查询事件
const reset = () => {
  console.log('reset', props.defultValue)
  console.log('reset', props.fields)
  for (const key in formModel.value) {
    console.log('========================')
    formModel.value[key] = props.defultValue[key] || undefined
  }
  console.log('reset', formModel.value)
  emit('update:modelValue', formModel.value)
  emit('search', formModel.value)
  emit('reset', formModel.value)
}

// 查询触发时，先校验表单，校验通过后发出事件
const handleSearch = async () => {
  try {
    await formRef.value?.validate?.()
    emit('search', formModel.value)
  } catch (e) {
    // 校验失败，用户可自行处理或显示错误
    console.error('Form validation failed:', e)
  }
}

// 初始化表单数据模型，合并传入的 modelValue
const initForm = () => {
  props.fields.forEach((field) => {
    if (!(field.prop in formModel.value)) {
      formModel.value[field.prop] = undefined
    }
  })
  Object.assign(formModel.value, props.modelValue || {})
}

// 获取绑定的键值
const getValuePropName = (item: FieldItem): string => {
  return item.formItemProps?.valuePropName || 'value'
}

// 是否显示item
const showFormItem = (item: FieldItem, index: number): boolean => {
  const { ifShow } = item
  if (typeof ifShow === 'boolean' && !ifShow) return false
  if (typeof ifShow === 'function' && !ifShow(formModel.value, item)) return false

  // 如果设置了 maxShowFields，并且没有展开 则限制显示的字段数量
  if (props.maxShowFields > 0 && index >= props.maxShowFields && !expanded.value) {
    return false
  }
  return true
}
//更新数据源
const updateFormModal = async (data: any) => {
  console.log('updateFormModal', data, props.fields)
  props.fields.forEach((field) => {
    if (field.prop in formModel.value) {
      formModel.value[field.prop] = data[field.prop]
    }
  })
  console.log('formModel.value', formModel.value)
  nextTick(() => {
    emit('update:modelValue', formModel.value)
    emit('search', formModel.value)
  })
}

// 监听本地数据变化，同步更新 v-model
watch(
  () => formModel.value,
  (val) => emit('update:modelValue', val),
  { deep: true }
)

// 组件挂载时初始化表单和加载数据源
onMounted(async () => {
  initForm()
})

// 对外暴露方法和属性
defineExpose({
  formRef,
  formModel,
  reset,
  handleSearch,
  toggleExpand: handleToggleExpand,
  updateFormModal
})
</script>

<style lang="scss">
.be-form {
  position: relative;
  padding: 20px;
  background-color: var(--color-white);
  .ant-form-item {
    margin-bottom: 24px;
  }
  // .ant-picker,
  // .ant-input,
  // .a-select {
  //   width: 100%;
  //   border-radius: 2px;
  // }
  .action-wrap {
    display: flex;
    align-items: center;
    .action-btn {
      display: flex;
      align-items: center;
      margin-right: 10px;
      .svg-icon {
        margin-right: 5px;
        font-size: 18px;
      }
    }
    .expand-btn {
      padding: 0;
      .svg-icon {
        transform: rotate(90deg);
      }
      &.expand {
        .svg-icon {
          transform: rotate(270deg);
        }
      }
    }
  }
}
.ant-table-tbody > tr > td {
  border-top: none !important;
}
</style>
